open Hashtbl
open Syntax
open BlockPopulation
open ProofAssembler
open TestCases
open Rules

				
type ecoSetting = {
	maxProofWidth : int;
	aprNumberOfLiveGenotypes : int;
	aprGenePoolTotComp : int;
	selectSize : int;
	selectReap  : int
	}
type genoStatus = Dead of float | Alive of float | Unborn
type genotype = program
type speciesInfo = {
	speciesId : int;
	ancesterID : int option;
	mutable fillProportion : float;
	mutable theoreticalMaxFill : int;
	mutable currentFill : int;
	mutable avgComplexity : float;
	mutable avgFitness : float;
	}
type population = {
	mutable info : speciesInfo;
	mutable contains_solution : bool;
	genotypes : (genotype, genoStatus) t 
	}
type species = proof
type ecosystem  = { 
	maxGenotypeScore : float;
	mutable solutions : term list;
	mutable speciesCtr : int;
	mutable generationCounter : int;
	mutable stats : string;
	settings : ecoSetting;
	goalType : ty; 
	mutable environment : test_case list;
	genes : gene_pool ref; 
	kingdom : (species,  population) t  
	} 

type eco_pop = Eco of ecosystem | Pop of population
val get_live : eco_pop -> (float * genotype) list

val get_species_from_id : ecosystem->int->species
val string_of_genotype : ?separator:string -> gene_pool->genotype->string
val card_population : ?pred:(genoStatus->bool) -> population -> int
val card_ecosystem : ?pred:(genoStatus->bool) -> ecosystem -> int
val empty_eco : gene_pool ref -> ecosystem

val add_species : ?debug:bool ->ecosystem -> proof -> int option -> int * int option
val modifyProofs : ?proofs:(species list) -> ecosystem->int->(int option * species) list
	
val make_eco : ?debug:bool -> gene_pool ref->ty->test_case list->ecoSetting -> ecosystem
val init_generation : ?debug:bool -> ecosystem -> constraint_function->int ref->term option
(*val next_generation : ?debug:bool -> ecosystem -> constraint_function->unit			  *)
(*val select_for_reap : ecosystem->unit *)